#include "FLog.h"
#include <QMutex>
#include <QDateTime>
#include <QCoreApplication>
#include <QStandardPaths>
#ifdef Q_OS_ANDROID
#include <QtAndroid>
#endif

QtMessageHandler gDefaultHandler = NULL;

void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    // 加锁,防止多线程中qdebug太频繁导致崩溃
    static QMutex mutex;
    QMutexLocker locker(&mutex);

    QString sType;
    switch (type) {
    case QtDebugMsg:    sType = "D"; break;
    case QtInfoMsg:     sType = "I"; break;
    case QtWarningMsg:  sType = "W"; break;
    case QtCriticalMsg: sType = "C"; break;
    case QtFatalMsg:    sType = "F"; break;
    }
    // 设置输出信息格式
    QString sTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    QString sMsg = QString("%1[%2]: %3").arg(sTime).arg(sType).arg(msg);
    // 输出到日志
    FLog::instance()->save(sMsg);
    // 输出到调试窗
    if (gDefaultHandler)
        gDefaultHandler(type, context, msg);
}

QScopedPointer<FLog> FLog::self;
FLog *FLog::instance()
{
    if (self.isNull()) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(new FLog);
        }
    }
    return self.data();
}

void FLog::start()
{
    gDefaultHandler = qInstallMessageHandler(MessageOutput);
}

void FLog::stop()
{
    qInstallMessageHandler(nullptr);
    gDefaultHandler = NULL;
}

void FLog::save(const QString &content)
{
    if (m_logDate != QDate::currentDate())
    {
        QString logFileName = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss.log");
        m_strFileName = m_strDir.filePath(logFileName);
        m_logDate = QDate::currentDate();
    }
    QFile outFile(m_strFileName);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
    QTextStream stream(&outFile);
    stream << content << endl;
    outFile.flush();
    outFile.close();
}

FLog::FLog(QObject *parent)
    : QObject(parent)
{
#ifdef Q_OS_ANDROID
    QString storagePer = "android.permission.WRITE_EXTERNAL_STORAGE";
    QtAndroid::PermissionResult r = QtAndroid::checkPermission(storagePer);
    if (r == QtAndroid::PermissionResult::Denied) {
        QtAndroid::requestPermissionsSync(QStringList() << storagePer);
    }
    QString logDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
    logDir.append("/").append(qApp->applicationName()).append("/Log");
#else
    QString logDir = qApp->applicationDirPath().append("/log");
#endif
    if (!m_strDir.exists(logDir))
        m_strDir.mkpath(logDir);
    m_strDir.setPath(logDir);
    qDebug() << "LogPath: " << logDir << ", isExist:" << m_strDir.exists();
    m_strFileName.clear();
}

FLog::~FLog()
{

}
